#pragma once

#include "EventLoop.h"
#include "Acceptor.h"
#include "Connection.h"
#include "LoopThreadPool.h"

class TcpServer
{
private:
    uint16_t _port;                                     // 服务器端口号
    uint64_t _next_id;                                  // 这是Connection和定时任务公用的ID，是自动增长的，可以标记连接的唯一性
    int _timeout;                                       // 非活跃连接超时时间
    bool _enable_inactive_release;                      // 是否启动非活跃连接超时销毁判断标志
    EventLoop _baseloop;                                // 主线程EVentLoop对象，负责监听事件的处理
    Acceptor _acceptor;                                 // 监听套接字管理对象
    LoopThreadPool _pool;                               // 这是从属EVentLoop线程池
    std::unordered_map<uint64_t, PtrConnection> _conns; // 保存管理对应的shared_ptr对象 -- 这里删除，就表示这个连接即将被释放

    // 用户设置的回调函数 -- 未来要设置给Connection
    using ConnectedCallback = std::function<void(const PtrConnection &)>;         // S/C连接成功时执行的函数
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>; // 消息处理函数
    using ClosedCallback = std::function<void(const PtrConnection &)>;            // 关闭连接时 调用
    using AnyEventCallback = std::function<void(const PtrConnection &)>;          // 任何事件都要执行
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;

private:
    // 1. 来一个连接构建一个Connection
    void NewConnection(int fd);

    // 2. 移除连接
    void RemoveConnectionInLoop(const PtrConnection &conn);

    // 3. 从管理Connection的_conns中移除连接信息
    void RemoveConnection(const PtrConnection &conn);

    void RunAfterInLoop(const Functor &task, int delay);

public:
    TcpServer(int port);

    // 1. 设置从属线程数量
    void SetThreadCount(int count);

    // 2. 设置连接成功回调函数
    void SetConnectedCallback(const ConnectedCallback &cb);

    // 3. 设置消息处理函数
    void SetMessageCallback(const MessageCallback &cb);

    // 4. 设置连接关闭函数
    void SetClosedCallback(const ClosedCallback &cb);

    // 5. 设置任意事件回调函数
    void SetAnyEventCallback(const AnyEventCallback &cb);

    // 6. 启动非活跃连接超时销毁
    void EnableInactiveRelease(int timeout);

    // 7. 添加定时任务
    void RunAter(const Functor &task, int delay);

    // 8. 启动服务器
    void Start();
};